package com.cm.projectx.controller.pricetask;


import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.text.StrPool;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.cm.projectx.entity.PriceTask;
import com.cm.projectx.entity.ProductInfo;
import com.cm.projectx.job.entity.JobParamEntity;
import com.cm.projectx.job.service.ScheduleService;
import com.cm.projectx.job.utils.JobParamConvert;
import com.cm.projectx.response.Result;
import com.cm.projectx.service.IPriceTaskService;
import com.cm.projectx.service.IProcessService;
import com.cm.projectx.service.IProductInfoService;
import com.cm.projectx.vo.QueryTaskListVo;
import com.cm.projectx.vo.TaskVo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/v2api/price/task")
public class PriceTaskController {
    private Logger logger = LoggerFactory.getLogger(PriceTaskController.class);
    @Autowired
    private ScheduleService scheduleService;
    @Autowired
    private IPriceTaskService priceTaskService;
    @Autowired
    private IProcessService processService;
    @Autowired
    private IProductInfoService productInfoService;
    /**
     * 添加任务
     * 1.保存任务表
     * 2.检查是否周期任务，如果是，定义定时任务后续自动处理
     * 3.提取任务选择的监测点、商品信息，可以存一个json字段
     * 4.循环发起监测点填报流程，保存回调流程id与任务id关联
     * 5.调用数据预置接口完成，填报表单的预置
     * @return
     */
    @RequestMapping("add")
    @Transactional(rollbackFor = Exception.class)
    public Result addTask(@RequestBody TaskVo taskVo){
        return priceTaskService.createAndDispatchTask(taskVo);
    }

    /**
     * 保存草稿接口
     * @param taskVo
     * @return
     */
    @RequestMapping("draftTask")
    public Result draftTask(@RequestBody TaskVo taskVo){
        Result result = new Result();
        try {
            if (StringUtils.isBlank(taskVo.getTaskCode())) {
                //不允许同名的有效任务
                long count = priceTaskService.count(Wrappers.<PriceTask>lambdaQuery()
                        .eq(PriceTask::getTaskName, taskVo.getTaskName()).ne(PriceTask::getStatus, "2"));
                if (count > 0) {
                    result.setCode(-1);
                    result.setMsg("任务重名");
                    return result;
                }
                //1 持久化任务信息
                String taskCode = UUID.randomUUID().toString().replaceAll("-", "");
                taskVo.setTaskCode(taskCode);
                // 草稿状态
                taskVo.setStatus(0);
                // 持久化任务信息
                priceTaskService.addTask(taskVo);
            }else {
                // 更新草稿 - 检查任务是否存在
                PriceTask existingTask = priceTaskService.getOne(Wrappers.<PriceTask>lambdaQuery().eq(PriceTask::getTaskCode, taskVo.getTaskCode()));
                if (existingTask == null) {
                    result.setCode(-1);
                    result.setMsg("任务不存在");
                    return result;
                }
                // 更新任务信息并保持状态为草稿
                taskVo.setStatus(0); // 保持草稿状态
                priceTaskService.updateTask(taskVo);
            }
            result.setCode(0);
            result.setMsg("保存草稿成功");
            return result;
        }catch (Exception e){
            result.setCode(-1);
            result.setMsg("保存草稿失败");
            logger.error("保存草稿异常", e);
        }
        return result;
    }

    /**
     * 废除接口
     * @param taskVo
     * @return
     */
    @RequestMapping("repealTask")
    public Result repealTask(@RequestBody TaskVo taskVo){
        Result result = new Result();
        try {
                //查任务是否存在
                PriceTask existingTask = priceTaskService.getOne(Wrappers.<PriceTask>lambdaQuery().eq(PriceTask::getTaskCode, taskVo.getTaskCode()));
                if (existingTask == null) {
                    result.setCode(-1);
                    result.setMsg("任务不存在");
                    return result;
                }
                // 更新任务状态为废除状态
                taskVo.setStatus(2);
                priceTaskService.updateTask(taskVo);
            result.setCode(0);
            result.setMsg("废除成功");
            return result;
        }catch (Exception e){
            result.setCode(-1);
            result.setMsg("废除成功失败");
            logger.error("废除成功异常", e);
        }
        return result;
    }
    /**
     * 根据条件导出文件
     *
     * @param response
     */
    @PostMapping("/export")
    public void exportExcel(@RequestBody QueryTaskListVo vo, HttpServletResponse response) throws IOException {
        // 调用service执行导出
        priceTaskService.exportExcel(vo,response);
    }
    /**
     * 停止任务关联的定时任务
     * @return
     */
    @RequestMapping("stop")
    public Result stopTask(@RequestParam int taskId){
        //如果是定时周期任务需要停止
        PriceTask task = priceTaskService.getById(taskId);
        JobParamEntity jobParam = JobParamConvert.convertByTaskScheduleType(task);
        scheduleService.pauseSchedule(jobParam.getJobName(), jobParam.getJobGroup());
        task.setStatus(3);
        priceTaskService.updateById(task);
        return Result.SUCCESS;
    }

    /**
     * 重启任务关联的定时任务
     * @return
     */
    @RequestMapping("resume")
    public Result resumeTask(@RequestParam int taskId){
        //如果expireTime已过期，需要重新配置
        PriceTask task = priceTaskService.getById(taskId);
        if (task.getStatus() == 0 && task.getExpireTime().after(new Date())){
            JobParamEntity jobParam = JobParamConvert.convertByTaskScheduleType(task);
            scheduleService.resumeSchedule(jobParam.getJobName(), jobParam.getJobGroup());
        }else {
            return new Result(-1, "任务已过有效时间", null);
        }
        return Result.SUCCESS;
    }

    /**
     * 更新任务的全量基础信息，检测定时周期是否有改变，及时更改定时任务的调度周期
     * @return
     */
    @RequestMapping("delay")
    public Result delayTask(@RequestBody TaskVo taskVo){
        PriceTask task = priceTaskService.getById(taskVo.getId());
        if (task.getStatus() == 1 && task.getExpireTime().after(new Date())){
            task.setExpireTime(taskVo.getExpireTime());
            priceTaskService.updateById(task);
        }else {
            return new Result(-1, "不可延期", null);
        }
        return Result.SUCCESS;
    }


    /**
     * 任务详情
     * 同时返回任务关联的各个流程的信息和状态，一个列表
     * @return
     */
    @RequestMapping("detail")
    public Result getTask(@RequestParam int taskId){
        Result result = new Result();
        PriceTask task = priceTaskService.getById(taskId);
        result.setCode(0);
        result.setMsg("业务成功");
        result.addData("task", task);
        if (task == null) {
            return result;
        }

        //商品详情
        List<Map<String, Object>> productList = new ArrayList<>();
        String productInfo = task.getProductMonitorRelations();
        if(StrUtil.isNotEmpty(productInfo)){
            JSONArray productArray = JSONUtil.parseArray(productInfo);
            for (Object o : productArray) {
                Map<String, Object> productMap = new HashMap<>();
                JSONObject product = (JSONObject) o;
                ProductInfo productDetail = productInfoService.getById(StrUtil.toString(product.get("productId")));
                if (productDetail == null) {
                    continue;
                }
                productMap.put("id", productDetail.getId());
                productMap.put("name", productDetail.getName());
                productMap.put("kind", productDetail.getKind());
                productMap.put("unit", productDetail.getUnit());
                productMap.put("floatingValue", ((BigDecimal)product.get("floatingValue")).floatValue());
                JSONArray monitors = (JSONArray) product.get("monitors");
                if(CollUtil.isNotEmpty(monitors)){
                    List<Object> monitorNames = monitors.stream().map(o1 -> ((JSONObject) o1).get("monitorName")).collect(Collectors.toList());
                    productMap.put("monitorPoints", StrUtil.join(StrPool.COMMA, monitorNames));
                }

                productList.add(productMap);
            }
        }
        result.addData("productList", productList);

        //查询所有的流程实例
        Object processList = processService.processList(taskId);
        result.addData("processList", processList);
        return result;
    }

    /**
     * 返回任务列表
     * @return
     */
    @RequestMapping("list")
    public Result listTask(QueryTaskListVo taskListVo){
        Result result = new Result();
        result.setCode(0);
        result.setMsg("业务成功");
        result.addData("list",  priceTaskService.getTaskList(taskListVo));
        return result;
    }
}
